package com.wangwei.spring.rabbit;

import com.wangwei.spring.rabbit.pojo.Order;
import com.wangwei.spring.rabbit.pojo.User;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerEndpoint;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.support.converter.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * 通过RabbitListenerConfigurer实现消息的消费
 * --1：实现RabbitListenerConfigurer接口，并把实现类托管到spring容器中
 * --2：在spring容器中，托管一个RabbitListenerContainerFactory的bean（SimpleRabbitListenerContainerFactory）
 * --3：在启动类上面加上@EnableRabbit
 *
 *   优点：使用RabbitListenerConfigurer可以一次注册多个RabbitListenerEndpoint。
 *        每个RabbitListenerEndpoint可以分别监听不同的queue，并采用不同的消费处理方式
 * Created by wangwei on 2019/10/14 0014.
 */
@Configuration
public class ConsumerConfig {
    @Bean
    public ConnectionFactory connectionFactory(){
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setUri("amqp://wangwei:wangwei@192.168.109.128:5672");
        //CacheModel:CHANNEL-默认，可以自动声明相关组件；CONNECTION-不会自动声明
        connectionFactory.setCacheMode(CachingConnectionFactory.CacheMode.CHANNEL);
        return connectionFactory;
    }

    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        rabbitAdmin.setAutoStartup(true);//true-默认，可自动声明；false-则不会自动声明
        return rabbitAdmin;
    }

    @Bean
    public RabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL); //手动确认
        return factory;
    }

    @Bean
    public RabbitListenerContainerFactory rabbitListenerContainerFactory2(ConnectionFactory connectionFactory){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(new MessageConverter() {
            @Override
            public Message toMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
                return null;
            }

            @Override
            public Object fromMessage(Message message) throws MessageConversionException {
                return new Body(message.getBody());
            }
        });
        return factory;
    }


//    @Bean
    public RabbitListenerConfigurer rabbitListenerConfigurer(){
        return new RabbitListenerConfigurer() {
            @Override
            public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
                SimpleRabbitListenerEndpoint endpoint = new SimpleRabbitListenerEndpoint();
                endpoint.setId("1");
                endpoint.setQueueNames("sms");
                endpoint.setMessageListener(msg -> {
                    System.out.println("-------------SimpleRabbitListenerEndpoint------------");
                    System.out.println(new String(msg.getBody()));
                });

                SimpleRabbitListenerEndpoint endpoint2 = new SimpleRabbitListenerEndpoint();
                endpoint2.setId("2");
                endpoint2.setQueueNames("mail","weixin");
                MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(new MessageHandler());
                messageListenerAdapter.setDefaultListenerMethod("ReceiveMsg");

                ContentTypeDelegatingMessageConverter converter = new ContentTypeDelegatingMessageConverter();
                TextMessageConverter textMessageConverter = new TextMessageConverter();
                converter.addDelegate("text",textMessageConverter);
                converter.addDelegate("html/text",textMessageConverter);
                converter.addDelegate("xml/text",textMessageConverter);
                converter.addDelegate("text/plain",textMessageConverter);

                Jackson2JsonMessageConverter jsonMessageConverter = new Jackson2JsonMessageConverter();
                DefaultJackson2JavaTypeMapper javaTypeMapper = new DefaultJackson2JavaTypeMapper();
                Map<String,Class<?>> idClassMapping = new HashMap<>();
                idClassMapping.put("order", Order.class);
                idClassMapping.put("user", User.class);
                javaTypeMapper.setIdClassMapping(idClassMapping);
                jsonMessageConverter.setJavaTypeMapper(javaTypeMapper);

                converter.addDelegate("json",jsonMessageConverter);
                converter.addDelegate("application/json",jsonMessageConverter);

                messageListenerAdapter.setMessageConverter(converter);
                endpoint2.setMessageListener(messageListenerAdapter);

                registrar.registerEndpoint(endpoint);
                registrar.registerEndpoint(endpoint2);
            }
        };
    }
}
